﻿namespace calendar_generator
{
	using System;
	using System.Linq;
	using System.Collections.Generic;

	public static class NewMoons
	{
		private static readonly Dictionary<int, List<string>> Years
			= new Dictionary<int, List<string>>
			{
				// Dates are in Universal Time (UT)
				{ 2010, new List<string> {"2010-02-14T02:52","2010-03-15T21:02","2010-04-14T12:30","2010-05-14T01:05","2010-06-12T11:15","2010-07-11T19:41","2010-08-10T03:09","2010-09-08T10:30","2010-10-07T18:45","2010-11-06T04:52","2010-12-05T17:36","2011-01-04T09:03"} },
				{ 2011, new List<string> {"2011-02-03T02:31","2011-03-04T20:47","2011-04-03T14:33","2011-05-03T06:51","2011-06-01T21:03","2011-07-01T08:55","2011-07-30T18:40","2011-08-29T03:05","2011-09-27T11:09","2011-10-26T19:56","2011-11-25T06:10","2011-12-24T18:07"} },
				{ 2012, new List<string> {"2012-01-23T07:40","2012-02-21T22:35","2012-03-22T14:38","2012-04-21T07:19","2012-05-20T23:48","2012-06-19T15:03","2012-07-19T04:25","2012-08-17T15:55","2012-09-16T02:11","2012-10-15T12:03","2012-11-13T22:09","2012-12-13T08:42","2013-01-11T19:44"} },
				{ 2013, new List<string> {"2013-02-10T07:21","2013-03-11T19:52","2013-04-10T09:36","2013-05-10T00:29","2013-06-08T15:57","2013-07-08T07:15","2013-08-06T21:51","2013-09-05T11:37","2013-10-05T00:35","2013-11-03T12:51","2013-12-03T00:23","2014-01-01T11:15"} },
				{ 2014, new List<string> {"2014-01-30T21:39","2014-03-01T08:00","2014-03-30T18:45","2014-04-29T06:15","2014-05-28T18:41","2014-06-27T08:09","2014-07-26T22:43","2014-08-25T14:14","2014-09-24T06:15","2014-10-23T21:57","2014-11-22T12:33","2014-12-22T01:36","2015-01-20T13:14"} },
				{ 2015, new List<string> {"2015-02-18T23:48","2015-03-20T09:37","2015-04-18T18:57","2015-05-18T04:14","2015-06-16T14:06","2015-07-16T01:25","2015-08-14T14:54","2015-09-13T06:42","2015-10-13T00:07","2015-11-11T17:48","2015-12-11T10:30","2016-01-10T01:31"} },
				{ 2016, new List<string> {"2016-02-08T14:39","2016-03-09T01:55","2016-04-07T11:24","2016-05-06T19:30","2016-06-05T03:00","2016-07-04T11:02","2016-08-02T20:45","2016-09-01T09:04","2016-10-01T00:12","2016-10-30T17:39","2016-11-29T12:19","2016-12-29T06:54"} },
				{ 2017, new List<string> {"2017-01-28T00:08","2017-02-26T14:59","2017-03-28T02:58","2017-04-26T12:17","2017-05-25T19:45","2017-06-24T02:31","2017-07-23T09:46","2017-08-21T18:31","2017-09-20T05:31","2017-10-19T19:13","2017-11-18T11:43","2017-12-18T06:31","2018-01-17T02:18"} },
				{ 2018, new List<string> {"2018-02-15T21:06","2018-03-17T13:12","2018-04-16T01:58","2018-05-15T11:48","2018-06-13T19:44","2018-07-13T02:48","2018-08-11T09:58","2018-09-09T18:02","2018-10-09T03:47","2018-11-07T16:03","2018-12-07T07:21","2019-01-06T01:29"} },
				{ 2019, new List<string> {"2019-02-04T21:04","2019-03-06T16:05","2019-04-05T08:51","2019-05-04T22:46","2019-06-03T10:03","2019-07-02T19:17","2019-08-01T03:12","2019-08-30T10:38","2019-09-28T18:27","2019-10-28T03:39","2019-11-26T15:06","2019-12-26T05:14"} },
				{ 2020, new List<string> {"2020-01-24T21:43","2020-02-23T15:33","2020-03-24T09:29","2020-04-23T02:27","2020-05-22T17:40","2020-06-21T06:42","2020-07-20T17:33","2020-08-19T02:42","2020-09-17T11:01","2020-10-16T19:31","2020-11-15T05:08","2020-12-14T16:17","2021-01-13T05:01"} },
			};

		public static List<DateTime> GetNewMoonsForYear(int year, string timeZoneId = "E. Europe Standard Time", bool noTime = true)
		{
			if (!Years.ContainsKey(year))
			{
				throw new ArgumentException(string.Format("There is no data for year of {0}.", year));
			}

			TimeZoneInfo timeZone = TimeZoneInfo.GetSystemTimeZones().Where(t => t.Id == timeZoneId).FirstOrDefault();
			if(timeZone == null)
			{
				throw new ArgumentException(string.Format("'{0}' is invalit Time Zone Id.", timeZone));
			}

			TimeSpan ts = timeZone.BaseUtcOffset;

			List<String> data = new List<string>();
			Years.TryGetValue(year, out data);

			List<DateTime> ret =
				new List<DateTime>(data.Select(d => DateTime.ParseExact(d, "yyyy-MM-ddTHH:mm", System.Globalization.CultureInfo.InvariantCulture)));

			ret = ret.Select(d => timeZone.IsDaylightSavingTime(d) ? d.Add(ts).AddHours(1) : d.Add(ts)).ToList();

			if (noTime)
			{
				ret = ret.Select(d => d.Date).ToList();
			}

			return ret;
		}
	}
}
